<?php
/**
 * Object Relational Persistence Mapping Class for table: ticket_item
 *
 * @package	com.clearhealth
 * @author	ClearHealth Inc.
 */

$loader->requireOnce('ordo/Service.class.php');
$loader->requireOnce('ordo/ExaminationType.class.php');
$loader->requireOnce('ordo/Insurance.class.php');

$loader->requireOnce('includes/ServiceDiscount/DiscountExecuter.class.php');
$loader->requireOnce('includes/ServiceDiscount/TicketItemPaymentFactory.class.php');

class TicketItem extends ORDataObject {

	/**#@+
	 * Fields of table: ticket_item mapped to class members
	 */
	var $ticket_item_id	= '';
	var $ticket_id		= '';
	var $doctor_id		= '';
	var $room_id		= '';
	var $item_id 		= '';
	var $item_order		= '';
	var $item_type		= '';
	var $status			= '';
	var $started		= '';
	var $closed			= '';
	var $discount		= '';
	var $pre_paid		= '';
	var $original_price = '';
	var $patient_price  = '';
	var $insurance_price = '';

	/**#@-*/

	const SERVICE_TYPE         =   "service";
	const TEST_TYPE            =   "laboratory";
	const COMPOSITE_SERVICE    =   "composite";
	const XRAY_TYPE            =   'x_ray';
	const ENDO_TYPE            =   'endoscopy';
	const ULTRA_TYPE           =   'ultra_sound';

	const OPEN         =   "open";
	const IN_PROGRESS  =   "in_progress";
	const WAITING      =   "waiting";
	const CLOSED       =   "closed";

	/**
	 * DB Table
	 */
	var $_table = 'ticket_item';

	/**
	 * Primary Key
	 */
	var $_key = 'ticket_item_id';

	/**
	 * Internal Name
	 */
	var $_internalName = 'TicketItem';

	/**
	 * Handle instantiation
	 */
	function TicketItem() {
		parent::ORDataObject();
	}

	public function setup($id = 0){
		$this->set('id',$id);
		if($id>0){
			$this->populate();
		}
	}

	public function populate(){
		parent::populate('ticket_item_id');
	}

	public function start($ticketItemId) {
		$sql = "UPDATE ticket_item SET started = NOW() WHERE ticket_item_id = $ticketItemId";
		$this->_execute($sql);
	}

	public function close($ticketItemId) {
		$sql = "UPDATE ticket_item SET closed = NOW() WHERE ticket_item_id = $ticketItemId";
		$this->_execute($sql);
	}

	public function getItemsFromTicket($ticketId) {
		$ds = new Datasource_sql();
		$sql = array (
			'cols'		=> "ticket_item_id, pre_paid, discount, item_type",
			'from'		=> "$this->_table",
			'where'		=> "ticket_id = $ticketId",
			);

		$ds->setup($this->_db, $sql);
		return $ds->toArray();
	}

	public function changeStatus($ticketItemId, $newStatus) {
		$sql = "UPDATE ticket_item SET status = '$newStatus' WHERE ticket_item_id = $ticketItemId";
		$this->_execute($sql);
	}

	public function checkCompositeDuplicated($ticketId, $compositeId){
		$sql = "SELECT ti.item_id
				FROM ticket_item ti
				WHERE ti.ticket_id = $ticketId AND ti.item_id = $compositeId AND ti.item_type = 'composite'";
		$res = $this->_execute($sql);
		if ($res and !$res->EOF) {
			return Celini::newORDO('CompositeService', $compositeId)->getLocalizedText('name');
		}
		return false;
	}

	public function addCompositeService($ticketId, $compositeId) {
		$composite = Celini::newORDO('CompositeService', $compositeId);
		$roomId = $composite->get('room_id');

		$ticketOrder = $this->getItemOrder($ticketId);
		$data = array (
				'ticket_id'		=> $ticketId,
				'room_id'		=> $roomId,
				'item_id'		=> $compositeId,
				'item_order'	=> $ticketOrder,
				'status'		=> 'open',
				'item_type'		=> self::COMPOSITE_SERVICE
		);
		$this->populateArray($data);
		$this->persist();
		$ticketItemId = $this->get_id();
		$compositeAsso = Celini::newORDO('CompositeServiceAsso', $compositeId);
		$compositeItems = $compositeAsso->listCompositeService($compositeId);
		foreach ($compositeItems as $item){
			if ($item['optional'] == 'no'){
				$compositeServiceItem = Celini::newORDO('CompositeServiceItem');
				$compositeServiceItem->addItem($ticketItemId, $item['service_id']);
			}
		}

		$ticket = Celini::newORDO('Ticket', $ticketId);
		$insuranceType = $ticket->get('insurance');

		$ticketInfo = $ticket->getTicketInfo();
		$discountExecuter = new DiscountExecuter($ticketInfo['sale_program_id']);
		$this->updateTicketItemPrice($ticketItemId, self::COMPOSITE_SERVICE, $insuranceType, $discountExecuter);
		return $ticketItemId;
	}

	public function updateCompositeService($ticketId, $ticketItemId, $compositeId, $compositeItems){
		$composite = Celini::newORDO('CompositeService', $compositeId);
		$roomId = $composite->get('room_id');

		$ticket = Celini::newORDO('Ticket', $ticketId);
		$promotionProgram = $ticket->get('sale_program_store_id');
		$insuranceType = $ticket->get('insurance');

		// Delete all old items of this composite services
		$compositeItem = celini::newORDO('CompositeServiceItem');
		$compositeItem->delete($ticketItemId);

		$compositeAsso = Celini::newORDO('CompositeServiceAsso', $compositeId);
		foreach ($compositeItems as $item){
			$compositeServiceItem = Celini::newORDO('CompositeServiceItem');
			$compositeServiceItem->addItem($ticketItemId, $item);
		}

		$ticketInfo = $ticket->getTicketInfo();
		$discountExecuter = new DiscountExecuter($ticketInfo['sale_program_id']);
		$this->updateTicketItemPrice($ticketItemId, self::COMPOSITE_SERVICE, $insuranceType, $discountExecuter);
		return $ticketItemId;

	}

	public function checkTestDuplicated($ticketId, $testId) {
		$sql = "SELECT ti.item_id
				FROM ticket_item ti
				WHERE ti.ticket_id = $ticketId AND ti.item_id = $testId";
		$res = $this->_execute($sql);
		if ($res and !$res->EOF) {
			return Celini::newORDO('Test', $testId)->getLocalizedText('name');
		}
		return false;
	}

	public function addLabAssignmentItem($ticketId, $labAssignmentTicketId,
	 $roomId, $originalPrice, $insurancePrice, $patientPrice) {
		$ticket = Celini::newORDO('Ticket', $ticketId);
        $promotionProgram = $ticket->get('sale_program_store_id');
        $insuranceType = $ticket->get('insurance');

        $ticketOrder = $this->getItemOrder($ticketId);
        $data = array (
                'ticket_id'     => $ticketId,
                'room_id'       => $roomId,
                'item_id'       => $labAssignmentTicketId,
                'original_price'       => $originalPrice,
                'insurance_price'       => $insurancePrice,
                'patient_price'       => $patientPrice,
                'item_order'    => $ticketOrder,
                'status'        => 'open',
                'item_type'     => TicketItem::TEST_TYPE
            );
        $this->populateArray($data);
        $this->persist();

        $ticketItemId = $this->get_id();
        /*
        $ticketInfo = $ticket->getTicketInfo();
        $discountExecuter = new DiscountExecuter($ticketInfo['sale_program_id']);
        $this->updateTicketItemPrice($ticketItemId, self::TEST_TYPE, $insuranceType, $discountExecuter);
        */

        return $ticketItemId;

	}

	public function addRadAssignmentItem($ticketId, $radTicketId, $itemType, $roomId,
            $originalPrice, $insurancePrice, $patientPrice) {
        $objTicket = Celini::newORDO('Ticket', $ticketId);
        // Information for discount calculation.
        $promotionProgram = $objTicket->get('sale_program_store_id');
        $insuranceType = $objTicket->get('insurance');

        $ticketOrder = $this->getItemOrder($ticketId);
        $data = array (
                'ticket_id'         => $ticketId,
                'room_id'           => $roomId,
                'item_id'           => $radTicketId,
                'original_price'    => $originalPrice,
                'insurance_price'   => $insurancePrice,
                'patient_price'     => $patientPrice,
                'item_order'        => $ticketOrder,
                'status'            => self::OPEN,
                'item_type'         => $itemType
            );
        $this->populateArray($data);
        $this->persist();
        $ticketItemId   =   $this->get_id();
        /*
        $ticketInfo = $ticket->getTicketInfo();
        $discountExecuter = new DiscountExecuter($ticketInfo['sale_program_id']);
        $this->updateTicketItemPrice($ticketItemId, self::RADIOLOGY_TYPE, $insuranceType, $discountExecuter);
        */

        return $ticketItemId;
	}

	public function addTest($ticketId, $testId, $testItem) {
		$test = Celini::newORDO('Test', $testId);
		$roomId = $test->get('room_id');

		$ticket = Celini::newORDO('Ticket', $ticketId);
		$promotionProgram = $ticket->get('sale_program_store_id');
		$insuranceType = $ticket->get('insurance');

		$ticketOrder = $this->getItemOrder($ticketId);
		$data = array (
				'ticket_id'		=> $ticketId,
				'room_id'		=> $roomId,
				'item_id'		=> $testId,
				'item_order'	=> $ticketOrder,
				'status'		=> 'open',
				'item_type'		=> TicketItem::TEST_TYPE
			);
		$this->populateArray($data);
		$this->persist();

		$ticketItemId = $this->get_id();
		$testItemOrdo = Celini::newORDO('TestItem');
		$testItemOrdo->addItem($ticketItemId, $testId, $testItem);

		$ticketInfo = $ticket->getTicketInfo();
		$discountExecuter = new DiscountExecuter($ticketInfo['sale_program_id']);
		$this->updateTicketItemPrice($ticketItemId, self::TEST_TYPE, $insuranceType, $discountExecuter);
		return $ticketItemId;
	}

	public function checkServiceDuplicated($ticketId, $serviceRoomId) {
		$servRoom = Celini::newORDO('ServiceRoom', $serviceRoomId);
		$servId = $servRoom->get('service_id');

		$sql = "SELECT ti.item_id
				FROM ticket_item ti
				WHERE ti.ticket_id = $ticketId AND ti.item_id = $servId";
		$res = $this->_execute($sql);
		if ($res and !$res->EOF) {
			return Celini::newORDO('Service', $servId)->getLocalizedText('name');
		}
		return false;
	}

	public function addService($ticketId, $servRoomId) {
		$serRoom = Celini::newORDO('ServiceRoom', $servRoomId);
		$ticket = Celini::newORDO('Ticket', $ticketId);
		$promotionProgram = $ticket->get('sale_program_store_id');

		$insuranceType = $ticket->get('insurance');
		$ticketOrder = $this->getItemOrder($ticketId);
		$itemId = $serRoom->get('service_id');

		$data = array (
				'ticket_id'		=> $ticketId,
				'room_id'		=> $serRoom->get('room_id'),
				'item_id'		=> $itemId,
				'item_order'	=> $ticketOrder,
				'status'		=> 'open',
				'item_type'		=> self::SERVICE_TYPE
			);
		$this->populateArray($data);
		$this->persist();

		$ticketItemId = $this->get_id();
		$servItem = Celini::newORDO('ServiceItem');
		$servItem->addItem($ticketItemId, $servRoomId);

		$ticketInfo = $ticket->getTicketInfo();
		$discountExecuter = new DiscountExecuter($ticketInfo['sale_program_id']);
		$this->updateTicketItemPrice($ticketItemId, self::SERVICE_TYPE,
			$insuranceType, $discountExecuter);
		return $ticketItemId;
	}

	/**
	 * Update ticket item prices based on
	 *    1. Insurance
	 *    2. Sale Program
	 *
	 * @param int $ticketItemId
	 * @param string $itemType
	 * @param string $insuranceType
	 * @param Discountable $discountExecuter
	 */
	public function updateTicketItemPrice($ticketItemId, $itemType,
			$insuranceType, $discountExecuter, $additionalData = array()) {
		$s = TicketItemPaymentFactory::createItemPayment($itemType, $discountExecuter);
		$s->add($ticketItemId, $insuranceType, $additionalData);
		$result = $s->getResult();
		$sql = "update ticket_item set
						original_price = " . $result['original_price'] . ",
						patient_price = " . $result['patient_price'] . ",
						insurance_price = " . $result['insurance_price'] . ",
						discount = " . $result['discount'] . "
					where ticket_item_id = $ticketItemId";
		$this->_execute($sql);
	}
	/**
	 * Update prices for ticket item
	 * @param $ItemId
	 * @param $itemType
	 * @param $data
	 * @return unknown_type
	 */

	public function updatePrices($ItemId, $itemType, $data) {
		$sql = "update ticket_item set
                original_price = " . $data['original_price'] . ",
                patient_price = " . $data['patient_price'] . ",
                insurance_price = " . $data['insurance_price'] . "
                where item_id = '$ItemId' AND item_type='$itemType'";
        $this->_execute($sql);
	}

	public function changeTicketItemPrice($ticketItemId, $itemType, $discountExecuter) {
		$s = TicketItemPaymentFactory::createItemPayment($itemType, $discountExecuter);
		$s->update($ticketItemId);
		$result = $s->getResult();
		$sql = "update ticket_item set
						original_price = " . $result['original_price'] . ",
						patient_price = " . $result['patient_price'] . ",
						insurance_price = " . $result['insurance_price'] . ",
						discount = " . $result['discount'] . "
					where ticket_item_id = $ticketItemId";
		$this->_execute($sql);
	}


	public function getLabItem($ticketItemId) {
		$ds = new Datasource_sql();
		$sql = array (
			'cols'		=> "TI.item_id, TI.room_id,
						TI.ticket_id, TI.ticket_item_id, TI.item_order, TI.status,
						TI.discount, TI.pre_paid,
						TI.original_price price, TI.patient_price, TI.insurance_price",
			'from'		=> "ticket_item TI",
			'where'		=> "TI.ticket_item_id = $ticketItemId",
			);

		$ds->setup($this->_db, $sql);
		$res = $ds->toArray();

		if (sizeof($res) > 0) {
			//$tmp = $this->getServiceInfo($res[0]['item_id'], self::TEST_TYPE);
			$paraClinicConfigObj = Celini::newOrdo('ParacliniqueConfig');
			$paraClinicConfig = $paraClinicConfigObj->getParaclinicConfig(EnumerationConstant::PARACLINIC_LAB);

			$res[0]['service_name'] = Utils::getEnumTextByValue(EnumerationConstant::PARACLINIC_TYPE,
			EnumerationConstant::PARACLINIC_LAB);
			$res[0]['payment_type'] = $paraClinicConfig['enum_payment_type'];
			$res[0]['room_name'] = Celini::newORDO('Room', $res[0]['room_id'])->getLocalizedText('name');
			return $res[0];
		}
		return false;
	}

	/**
	 * Get information on an ticket_item record of radiology type
	 *
	 * @param int $ticketItemId Ticket item Id
	 */
	public function getRadItem($ticketItemId) {
        $ds = new Datasource_sql();
        $sql = array (
            'cols'      => "TI.item_id, TI.room_id, TI.item_type,
                        TI.ticket_id, TI.ticket_item_id, TI.item_order, TI.status,
                        TI.discount, TI.pre_paid,
                        TI.original_price price, TI.patient_price, TI.insurance_price",
            'from'      => "ticket_item TI",
            'where'     => "TI.ticket_item_id = $ticketItemId"
            );

        $ds->setup($this->_db, $sql);
        $res = $ds->toArray();

        if (sizeof($res) > 0) {
        	$typeConstant  =   "";
        	if ($res[0]['item_type'] == self::ENDO_TYPE) {
        		$typeConstant =   EnumerationConstant::PARACLINIC_ENDO;
        	}
        	elseif ($res[0]['item_type'] == self::XRAY_TYPE) {
                $typeConstant =   EnumerationConstant::PARACLINIC_XRAY;
        	}
        	elseif ($res[0]['item_type'] == self::ULTRA_TYPE){
        		$typeConstant =   EnumerationConstant::PARACLINIC_ULTRA;
        	}
        	$paraClinicConfigObj = Celini::newOrdo('ParacliniqueConfig');
            $paraClinicConfig = $paraClinicConfigObj->getParaclinicConfig($typeConstant);

            $res[0]['service_name'] = Utils::getEnumTextByValue(EnumerationConstant::PARACLINIC_TYPE, $typeConstant);
            $res[0]['payment_type'] = $paraClinicConfig['enum_payment_type'];
            $res[0]['paraclinic_type'] =  Utils::getEnumKey(EnumerationConstant::PARACLINIC_TYPE, $typeConstant);
            $res[0]['room_name'] = Celini::newORDO('Room', $res[0]['room_id'])->getLocalizedText('name');
            return $res[0];
        }
        return false;
	}

	public function getCompositeItem($ticketItemId) {
		$ds = new Datasource_sql();
		$sql = array (
			'cols'		=> "TI.item_id, TI.room_id,
						TI.ticket_id, TI.ticket_item_id, TI.item_order, TI.status,
						TI.discount, TI.pre_paid,
						TI.original_price price, TI.patient_price, TI.insurance_price",
			'from'		=> "ticket_item TI",
			'where'		=> "TI.ticket_item_id = $ticketItemId",
			);

		$ds->setup($this->_db, $sql);
		$res = $ds->toArray();

		if (sizeof($res) > 0) {
			$tmp = $this->getServiceInfo($res[0]['item_id'], self::COMPOSITE_SERVICE);
			$res[0]['service_name'] = $tmp['service_name'];
			$res[0]['payment_type'] = $tmp['payment_type'];
			$res[0]['room_name'] = Celini::newORDO('Room', $res[0]['room_id'])->getLocalizedText('name');
			return $res[0];
		}
		return false;
	}

	public function getServiceItem($ticketItemId) {
		$ds = new Datasource_sql();
		$sql = array (
			'cols'		=> "TI.item_id, TI.room_id,
						TI.ticket_id, TI.ticket_item_id, TI.item_order, TI.status,
						TI.discount , TI.pre_paid,
						TI.original_price price, TI.patient_price, TI.insurance_price",
			'from'		=> "$this->_table TI",
			'where'		=> "TI.ticket_item_id = $ticketItemId",
			);

		$ds->setup($this->_db, $sql);
		$res = $ds->toArray();
		if (sizeof($res) > 0) {
			$tmp = $this->getServiceInfo($res[0]['item_id'], self::SERVICE_TYPE);
			$res[0]['service_name'] = $tmp['service_name'];
			$res[0]['payment_type'] = $tmp['payment_type'];
			$roomId = $res[0]['room_id'];
			$res[0]['room_name'] = Celini::newORDO('Room', $roomId)->getLocalizedText('name');

			return $res[0];
		}
		return false;
	}

	public function getTicketItemId($itemId, $itemType) {
		$ds = new Datasource_sql();
        $sql = array (
            'cols'      => "ticket_item_id",
            'from'      => "$this->_table",
            'where'     => "item_id = '$itemId' AND item_type='$itemType'",
       );
       $ds->setup($this->_db, $sql);
        $res = $ds->toArray();
        if (sizeof($res) > 0) {
        	return $res[0]['ticket_item_id'];
        }
		return 0;
	}

	public function delete($ticketItemId) {
		// delete service item if available
		$serviceItem = Celini::newORDO('ServiceItem');
		$serviceItem->delete($ticketItemId);

		// delete test item if available
		$testItem = Celini::newORDO("TestItem");
		$testItem->delete($ticketItemId);

		// delete composite service item if available
		$compositeItem = Celini::newORDO("CompositeServiceItem");
		$compositeItem->delete($ticketItemId);

		// delete queue item if available
		$queueItem = Celini::newORDO("QueueItem");
		$queueItem->delete($ticketItemId);

		$this->setup($ticketItemId);
		$order = $this->get('item_order');
		$ticketId = $this->get('ticket_id');
		$sql = "update ticket_item set item_order = item_order - 1
			 where ticket_id = $ticketId  AND item_order > $order";
		$this->_execute($sql);

		// delete the ticket item
		$sql = "delete from ticket_item where ticket_item_id = $ticketItemId";
		$this->_execute($sql);
	}

	public function prePaid($ticketItemId, $amount) {
		$sql = "update ticket_item set pre_paid = pre_paid + " . $amount ." where ticket_item_id = " . $ticketItemId;
		$this->_execute($sql);
		$sql = "select pre_paid from ticket_item where ticket_item_id = " . $ticketItemId;
		$res = $this->_execute($sql);
		if ($res &&!$res->EOF) {
			return $res->fields['pre_paid'];
		}
		return 0;
	}

	public function serviceNameAndPaymentType($ticketITemId) {
		$this->setup($ticketITemId);
		$type = $this->get('item_type');
		$id = $this->get('item_id');
		$tmp = $this->getServiceInfo($id, $type);
		return array('name' => $tmp['service_name'],
					'payment_type' => $tmp['payment_type']);
	}

	public function isPaymentType($ticketItemId, $paymentType) {
		$this->setup($ticketItemId);
		$type = $this->get('item_type');
		$id = $this->get('item_id');
		$tmp = $this->getServiceInfo($id, $type);

		if ($tmp['payment_type'] == $paymentType) {
			return true;
		}
		return false;
	}

	public function getPatientFromTicketItem($ticketItemId) {
		$ti = Celini::newORDO('TicketItem', $ticketItemId);
		$ticket = Celini::newORDO('Ticket', $ti->get('ticket_id'));
		return $ticket->get('patient_id');
	}

	public function getItembyOrder($ticketId, $order) {
		$res = $this->_execute("select ticket_item_id from ticket_item where ticket_id = $ticketId and item_order = $order");
		if ($res && !$res->EOF) {
			return $res->fields['ticket_item_id'];
		}
		return false;
	}

	public function getFirstService($ticketId) {
		$sql = "select item_id
				from ticket_item
				where ticket_id = $ticketId
				order by item_order
				limit 1";

		$res = $this->_execute($sql);
		if ($res && !$res->EOF) {
			return $res->fields['item_id'];

		}

		return '';

	}

	public function preCheckOrdering($up) {
		$ticketId = $this->get('ticket_id');
		// turn up
		if ($up) {
			$order = $this->get('item_order') - 1;
			$res = $this->_execute("select status from ticket_item where ticket_id = $ticketId and item_order = " . $order);
			if ($res->fields['status'] == self::IN_PROGRESS) {
				return true;
			}
		}
		// turn down
		else {
			if ($this->get('status') == self::IN_PROGRESS) {
				return true;
			}
		}
		return false;
	}

	public function turnDown() {
		$ticketId = $this->get('ticket_id');
		$order = $this->get('item_order');

		$nextOrder = $order + 1;
		$res = $this->_execute("select ticket_item_id from ticket_item where ticket_id = $ticketId and item_order = $nextOrder");
		$replacementId = $res->fields['ticket_item_id'];

		$this->_execute("update ticket_item set item_order = $nextOrder where ticket_item_id = " . $this->get_id());
		$this->_execute("update ticket_item set item_order = $order where ticket_item_id = $replacementId");
	}

	public function turnUp() {
		$ticketId = $this->get('ticket_id');
		$order = $this->get('item_order');

		if ($order == 1) {
			return;
		}

		$nextOrder = $order - 1;
		$res = $this->_execute("select ticket_item_id from ticket_item where ticket_id = $ticketId and item_order = $nextOrder");
		$replacementId = $res->fields['ticket_item_id'];

		$this->_execute("update ticket_item set item_order = $nextOrder where ticket_item_id = " . $this->get_id());
		$this->_execute("update ticket_item set item_order = $order where ticket_item_id = $replacementId");
	}

	public function isExist($ticketItemId){
		$sql ="select * from ticket_item where ticket_item_id = $ticketItemId";
		$res = $this->_execute($sql);
		if ($res && !$res->EOF) {
			return true;
		}
		return false;
	}

	public function getEncounterTypeFromTicketItemId($ticketItemId = 0) {
		if ($ticketItemId == 0) {
			$ticketItemId = $this->ticket_item_id;
		}
		$sql = "SELECT SEM.encounter_type FROM $this->_table TI
				LEFT JOIN service_encounter_map SEM ON TI.item_id = SEM.service_id
				WHERE TI.ticket_item_id = $ticketItemId";
		$res = $this->_execute($sql);
		if (empty($res)) {
			return 0;
		}
		return $res->fields['encounter_type'];
	}

	public function updateNewFee($itemId, $newFee) {
		$this->_execute("UPDATE $this->_table SET patient_price = $newFee WHERE ticket_item_id = $itemId");

		$this->setup($itemId);
		$ticket = Celini::newORDO('Ticket', $this->ticket_id);
		$ticketInfo = $ticket->getTicketInfo();
		$discountExecuter = new DiscountExecuter($ticketInfo['sale_program_id']);
		$this->changeTicketItemPrice($itemId, $this->item_type, $discountExecuter);
	}

	private function getItemOrder($ticketId) {
		$ti = new TicketItem();
		$sql = "select max(item_order) num_item from ticket_item where ticket_id = $ticketId";
		$res = $ti->_execute($sql);
		if ($res && !$res->EOF) {
			return $res->fields['num_item'] + 1;
		}
		return 1;
	}


	private function getServiceInfo($id, $type) {
		$result = array('service_name' => '',
					'payment_type'	=> '');
		if ($type == self::SERVICE_TYPE) {
			$ordo = Celini::newORDO('Service', $id);
		} else if ($type == self::TEST_TYPE) {
		    //laboratory configure information
			$paraClinicConfigObj = Celini::newOrdo('ParacliniqueConfig');
			$paraClinicConfig = $paraClinicConfigObj->getParaclinicConfig(EnumerationConstant::PARACLINIC_LAB);
			$result['service_name'] = Utils::getEnumTextByKey(EnumerationConstant::PARACLINIC_TYPE,
			 $paraClinicConfig['enum_paraclinic_type']);
			$result['payment_type'] = Utils::getEnumValue(EnumerationConstant::PAYMENT_TYPE,
			 $paraClinicConfig['enum_payment_type']);
            return $result;
		} else if ($type == self::COMPOSITE_SERVICE) {
			$ordo = Celini::newORDO('CompositeService', $id);
		} else {
			return $result;
		}
		$result['service_name'] = $ordo->getLocalizedText('name');
		$result['payment_type'] = $ordo->get('payment_type');
		return $result;
	}

	public function getRecentPatient($userId, $limit = 20) {
		$date = date('Y-m-d');
		$sql = "SELECT DISTINCT(t.patient_id) AS patient_id, p.name, pa.patient_code
				FROM $this->_table ti
				LEFT JOIN ticket t ON (t.ticket_id = ti.ticket_id)
				LEFT JOIN person p ON (t.patient_id = p.person_id)
				LEFT JOIN patient pa ON (t.patient_id = pa.person_id)
				WHERE ti.doctor_id = $userId AND ti.status = 'closed' AND DATE(ti.closed) = '$date'
				ORDER BY ti.closed DESC
				LIMIT $limit";
		return $this->_execute($sql);
	}

	/**
	 * Get ticket items of service type.
	 *
	 * @param int Ticket Id
	 * @return array Result array
	 */
	public function getServiceItemsByTicket($ticketId) {
        $field  =   L10nHelper::changeField(L10nHelper::getLocale(), 'name');
        
        $itemType   =   self::SERVICE_TYPE;
		$ds = new Datasource_sql();
        $sql = array (
            'cols'      => "TI.item_id, TI.room_id, TI.item_type,
                        TI.ticket_id, TI.ticket_item_id, TI.item_order, TI.status, TI.discount ,
                        TI.pre_paid, TI.original_price price, TI.patient_price, TI.insurance_price,
                        S.payment_type, S.$field service_name, R.$field room_name, QI.queue_id",
            'from'      => "$this->_table TI
                            INNER JOIN service S ON (S.service_id=TI.item_id AND TI.ticket_id = '$ticketId' AND TI.item_type='$itemType')
                            LEFT JOIN room R ON (TI.room_id=R.room_id)
                            LEFT JOIN queue_item QI ON (TI.ticket_item_id=QI.ticket_item_id AND TI.ticket_id=QI.ticket_id)",
            );

        $ds->setup($this->_db, $sql);
        $res = $ds->toArray();

        return $res;
	}

    public function getCompositeItemsByTicket($ticketId) {
        $field  =   L10nHelper::changeField(L10nHelper::getLocale(), 'name');
        
        $itemType   =   self::COMPOSITE_SERVICE;
        $ds = new Datasource_sql();
        $sql = array (
            'cols'      => "TI.item_id, TI.room_id, TI.item_type,
                        TI.ticket_id, TI.ticket_item_id, TI.item_order, TI.status, TI.discount ,
                        TI.pre_paid, TI.original_price price, TI.patient_price, TI.insurance_price,
                        CS.$field service_name, R.$field room_name, QI.queue_id, CS.payment_type",
            'from'      => "$this->_table TI
                            INNER JOIN composite_service CS ON (CS.composite_service_id=TI.item_id AND TI.ticket_id = '$ticketId' AND TI.item_type='$itemType')
                            LEFT JOIN room R ON (TI.room_id=R.room_id)
                            LEFT JOIN queue_item QI ON (TI.ticket_item_id=QI.ticket_item_id AND TI.ticket_id=QI.ticket_id)",
            );

        $ds->setup($this->_db, $sql);
        $res = $ds->toArray();

        return $res;
    }

    public function getLabItemsByTicket($ticketId) {
        $field  =   L10nHelper::changeField(L10nHelper::getLocale(), 'name');
        
        $itemType   =   self::TEST_TYPE;
        $ds         =   new Datasource_sql();

        $paraClinicConfigObj    =   Celini::newOrdo('ParacliniqueConfig');
        $paraClinicConfig       =   $paraClinicConfigObj->getParaclinicConfig(EnumerationConstant::PARACLINIC_LAB);
        $serviceName            =   Utils::getEnumTextByValue(EnumerationConstant::PARACLINIC_TYPE,
            EnumerationConstant::PARACLINIC_LAB);
        $paymentType            =   ($paraClinicConfig['enum_payment_type'] == Utils::getEnumKey(EnumerationConstant::PAYMENT_TYPE,
                EnumerationConstant::PAYMENT_TYPE_AFTER))? Service::AFTER : Service::BEFORE;

        $sql = array (
            'cols'      =>  "TI.item_id, TI.room_id, TI.item_type,
                            TI.ticket_id, TI.ticket_item_id, TI.item_order, TI.status, TI.discount ,
                            TI.pre_paid, TI.original_price price, TI.patient_price, TI.insurance_price,
                            '$serviceName' service_name, R.$field room_name, QI.queue_id, '$paymentType' payment_type",
            'from'      =>  "$this->_table TI
                            LEFT JOIN room R ON (TI.room_id=R.room_id)
                            LEFT JOIN queue_item QI ON (TI.ticket_item_id=QI.ticket_item_id AND TI.ticket_id=QI.ticket_id)",
            'where'     =>  "TI.ticket_id='$ticketId' AND TI.item_type='$itemType'"
            );

        $ds->setup($this->_db, $sql);
        $res = $ds->toArray();

        return $res;
    }

    public function getRadItemsByTicket($ticketId) {
        $field  =   L10nHelper::changeField(L10nHelper::getLocale(), 'name');
        
        $endoType   =   self::ENDO_TYPE;
        $xrayType   =   self::XRAY_TYPE;
        $ultraType  =   self::ULTRA_TYPE;
        $ds         =   new Datasource_sql();
        $sql = array (
            'cols'      => "TI.item_id, TI.room_id, TI.item_type,
                            TI.ticket_id, TI.ticket_item_id, TI.item_order, TI.status, TI.discount ,
                            TI.pre_paid, TI.original_price price, TI.patient_price, TI.insurance_price,
                            R.$field room_name, QI.queue_id",
            'from'      => "$this->_table TI
                            LEFT JOIN room R ON (TI.room_id=R.room_id)
                            LEFT JOIN queue_item QI ON (TI.ticket_item_id=QI.ticket_item_id AND TI.ticket_id=QI.ticket_id)",
            'where'     =>  "TI.ticket_id='$ticketId' AND TI.item_type IN ('$endoType', '$xrayType', '$ultraType')"
            );
        $ds->setup($this->_db, $sql);
        $res = $ds->toArray();
        $paraClinicConfigObj    =   Celini::newOrdo('ParacliniqueConfig');
        foreach ($res as &$item) {
        	$constType =   '';
            if ($item['item_type'] == self::ENDO_TYPE) {
            	$constType =   EnumerationConstant::PARACLINIC_ENDO;
            }
            elseif ($item['item_type'] == self::XRAY_TYPE) {
                $constType =   EnumerationConstant::PARACLINIC_XRAY;
            }
            else if($item['item_type'] == self::ULTRA_TYPE){
                $constType =   EnumerationConstant::PARACLINIC_ULTRA;
            }
            $paraClinicConfig   =   $paraClinicConfigObj->getParaclinicConfig($constType);
            $serviceName        =   Utils::getEnumTextByValue(EnumerationConstant::PARACLINIC_TYPE, $constType);
            $paymentType        =   $paraClinicConfig['enum_payment_type'];
            $item['service_name']   =   $serviceName;
            $item['payment_type']   =   ($paymentType == Utils::getEnumKey(EnumerationConstant::PAYMENT_TYPE,
                EnumerationConstant::PAYMENT_TYPE_AFTER))? Service::AFTER : Service::BEFORE;
        }

        return $res;
    }
}
?>
